import { JSDOM } from "jsdom";
import { marked } from "marked";
import {
	ArticleContentDataType,
	ArticleContentDataVersion,
	type Article,
	type ArticleContentNode,
	type ArticleContentNodeV1,
} from "@/types/article";
import { MarkdownHeading } from "astro";

const document = new JSDOM().window.document;
function renderNodeV1(node: ArticleContentNodeV1): HTMLElement {
	// 副标题
	if (node.type === "subtitle") {
		const h2 = document.createElement("h2");
		h2.textContent = typeof node.value === "string" ? node.value : "";
		return h2;
	}
	// 段落
	else if (node.type === "paragraph") {
		const p = document.createElement("p");

		// 遍历并处理段落中的子节点
		const 遍历段落子节点 = (
			parent: HTMLElement,
			childNode?: ArticleContentNodeV1,
		) => {
			if (!childNode) {
				return;
			}
			// 替换字符串中的尖括号
			if (typeof childNode.value === "string") {
				childNode.value = childNode.value
					.replaceAll("<", "&lt;")
					.replaceAll(">", "&gt;");
			}
			if (childNode.type === "text" || childNode.type === "#text") {
				parent.innerHTML += childNode.value;
				return;
			}

			// 老版本 和 date, time
			// 处理单个节点
			if (!Array.isArray(childNode.value)) {
				parent.innerHTML += `<${childNode.type}>${childNode.value}</${childNode.type}>`;
			}
			// 新版本, node.value 为 数组
			// 处理包含多个子节点的情况
			else {
				// 创建子节点，并遍历子节点内容，再加回父节点
				const childElement = document.createElement(childNode.type);
				for (let index = 0; index < childNode.value.length; index++) {
					const n = childNode.value[index];
					遍历段落子节点(childElement, n);
				}
				parent.appendChild(childElement);
			}
		};

		const childCount = Array.isArray(node.value) ? node.value.length : 0;
		for (let j = 0; j < childCount; j++) {
			const child = node.value[j];
			遍历段落子节点(p, child);
		}
		return p;
	}
	// 图片
	else if (node.type === "figure") {
		const figure = document.createElement("figure");
		figure.className = "article-figure";

		const [img, figcaption] = Array.isArray(node.value) ? node.value : [];
		if (img) {
			const imgSrc = typeof img.value === "string" ? img.value : "";
			const imgElement = document.createElement("img");
			imgElement.decoding = "async";
			imgElement.loading = "lazy";
			imgElement.dataset.src = imgSrc;
			imgElement.src = imgSrc; // 占位图src
			imgElement.onload = () => {
				if (imgElement.src !== imgSrc) imgElement.src = imgSrc; // 实际图src
				imgElement.onload = null;
			};
			imgElement.onerror = () => {
				imgElement.src = ""; // 图片加载失败的备选图
			};
			figure.appendChild(imgElement);
		}
		if (figcaption) {
			const figcaptionElement = document.createElement("figcaption");
			figcaptionElement.textContent =
				typeof figcaption.value === "string" ? figcaption.value : "";
			figure.appendChild(figcaptionElement);
		}
		return figure;
	}
	// 其他
	else {
		const valueString = typeof node.value === "string" ? node.value : "";
		const unknownElement = document.createElement(node.type);
		// 图片
		if (node.type === "img") {
			unknownElement.setAttribute("src", valueString);
			if (node.alt) unknownElement.setAttribute("alt", node.alt);
		}
		// 不是图片
		else {
			unknownElement.textContent = valueString;
		}
		return unknownElement;
	}
}

function renderNodeV2(node: ArticleContentNode): HTMLElement {
	// 段落
	if (node.type === "paragraph" || node.tagName === "p") {
		const p = document.createElement(node.tagName);

		// 遍历并处理段落中的子节点
		const 遍历段落子节点 = (
			parent: HTMLElement,
			childNode?: ArticleContentNode,
		) => {
			if (!childNode) {
				return;
			}
			// 替换字符串中的尖括号
			if (childNode.textContent) {
				childNode.textContent = childNode.textContent
					.replaceAll("<", "&lt;")
					.replaceAll(">", "&gt;");
			}

			// 普通文本节点
			if (childNode.type === "text" || childNode.type === "#text") {
				parent.innerHTML += childNode.textContent;
				return; // 结束
			}

			// 子节点处理
			if (!childNode.children) return;
			// 处理单个节点
			if (childNode.children.length === 0) {
				parent.innerHTML += `<${childNode.tagName}>${childNode.textContent}</${childNode.tagName}>`;
			}
			// 处理包含多个子节点的情况
			else {
				// 创建子节点，并遍历子节点内容，再加回父节点
				const childElement = document.createElement(childNode.tagName);
				for (let index = 0; index < childNode.children.length; index++) {
					const n = childNode.children[index];
					遍历段落子节点(childElement, n);
				}
				parent.appendChild(childElement);
			}
		};

		for (let j = 0; j < (node.children ? node.children.length : 0); j++) {
			const childNode = node.children?.[j];
			遍历段落子节点(p, childNode);
		}
		return p;
	}
	// 图片
	else if (node.type === "figure") {
		const figure = document.createElement(node.tagName);
		figure.className = "article-figure";

		const [img, figcaption] = node.children || [];
		if (img) {
			const imgElement = document.createElement("img");
			imgElement.decoding = "async";
			imgElement.loading = "lazy";
			imgElement.dataset.src = img.src;
			imgElement.src = ""; // 占位图src
			imgElement.onload = () => {
				if (imgElement.src !== img.src) {
					imgElement.src = img.src || ""; // 实际图src
				}
				imgElement.onload = null;
			};
			imgElement.onerror = () => {
				imgElement.src = ""; // 图片加载失败的备选图
			};
			figure.appendChild(imgElement);
		}
		if (figcaption) {
			const figcaptionElement = document.createElement("figcaption");
			figcaptionElement.textContent = figcaption.textContent || "";
			figure.appendChild(figcaptionElement);
		}
		return figure;
	}
	// 其他
	else {
		const unknownElement = document.createElement(node.tagName);
		unknownElement.textContent = node.textContent || "";
		if (node.href) {
			unknownElement.setAttribute("href", node.href);
		}
		if (node.alt) {
			unknownElement.setAttribute("alt", node.alt);
		}
		if (node.src) {
			unknownElement.setAttribute("src", node.src);
		}
		return unknownElement;
	}
}

export function renderArticle(article: Article): string {
	const articleElement = document.createElement("article");
	const articleContentData = article.contentData;
	// json v1
	if (
		articleContentData.type === ArticleContentDataType.JSON &&
		(articleContentData.version === ArticleContentDataVersion.V1 ||
			articleContentData.jsonVersion === ArticleContentDataVersion.V1) &&
		Array.isArray(articleContentData.content)
	) {
		for (let index = 0; index < articleContentData.content.length; index++) {
			const node = articleContentData.content[index];
			articleElement.appendChild(renderNodeV1(node));
		}
	}
	// json v2
	else if (
		articleContentData.type === ArticleContentDataType.JSON &&
		articleContentData.version === ArticleContentDataVersion.V2 &&
		Array.isArray(articleContentData.content)
	) {
		// console.log("json v2");
		for (let index = 0; index < articleContentData.content.length; index++) {
			const node = articleContentData.content[index];
			articleElement.appendChild(renderNodeV2(node));
		}
	}
	// markdown
	else if (articleContentData.type === ArticleContentDataType.Markdown) {
		articleElement.innerHTML = marked(articleContentData.content || "", {
			async: false,
		});
	} else if (
		articleContentData.type === ArticleContentDataType.HTML ||
		articleContentData.type === ArticleContentDataType.Unknown
	) {
		return articleContentData.content || "";
	}

	initHeadingElements(articleElement);
	return articleElement.innerHTML;
}

function initHeadingElements(contentElement: HTMLElement) {
	let imageElementCount = 0;
	function getHeadingID(text: string) {
		return text
            .toLowerCase()
            .replace(/^-+|-+$/g, '');     // 移除首尾的连字符
	}
	function getImageID(text?: string) {
		return `[图片]${text ? text + "-" : ""}${++imageElementCount}`
	}

	for (const element of contentElement.children) {
		const e: HTMLElement & { alt?: string } = element as HTMLElement;
		if (e.tagName === "IMG") {
			e.id = getImageID(e.alt);
			continue;
		}
		// p 内的图片
		else if (e.tagName === "P") {
			const images = e.getElementsByTagName("IMG");
			if (images.length === 0) {
				continue;
			}
			for (const ie of images) {
				const imageElement: HTMLElement & { alt?: string } = ie as HTMLElement;
				imageElement.id = getImageID(imageElement.alt);
			}
			continue;
		}
		// figure 图片
		else if (e.tagName === "FIGURE") {
			const figcaption = e.getElementsByTagName("FIGCAPTION")[0];
			e.id = getImageID(figcaption.textContent);
			continue;
		}

		// 不是标题
		if (!e.tagName.startsWith('H')) {
			continue;
		}
        // 设置标题ID
		e.id = getHeadingID(e.textContent?.trim() || "");
	}
}

export function renderArticleHeadings(html: string): MarkdownHeading[] {
	function getImageText(text?: string) {
		return `[图片]${text}`;
	}

	const headings: MarkdownHeading[] = [];

    // 创建一个临时DOM元素来解析HTML
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = html;

    for (const element of tempDiv.children) {
		const e: HTMLElement & { alt?: string } = element as HTMLElement;
		if (!e.id) {
			continue;
		}
		if (e.tagName === "IMG") {
			headings.push({
				depth: 2,
				text: getImageText(e.alt),
				slug: e.id,
			})
			continue;
		}
		// p 内的图片
		else if (e.tagName === "P") {
			const images = e.getElementsByTagName("IMG");
			if (images.length === 0) {
				continue;
			}
			for (const ie of images) {
				if (!ie.id) {
					continue;
				}
				const imageElement: HTMLElement & { alt?: string } = ie as HTMLElement;
				headings.push({
					depth: 2,
					text: getImageText(imageElement.alt),
					slug: imageElement.id,
				});
			}
			continue;
		}
		// figure 图片
		else if (e.tagName === "FIGURE") {
			const figcaption = e.getElementsByTagName("FIGCAPTION")[0];
			headings.push({
				depth: 2,
				text: getImageText(figcaption.textContent || e.alt),
				slug: e.id,
			});
			continue;
		}

		// 不是标题
		if (!e.tagName.startsWith('H')) {
			continue;
		}
        // 获取标题级别
        const depth = parseInt(e.tagName.replace('h', ''), 10);
        const text = element.textContent?.trim() || '';
        // 生成slug（URL友好的标识符）
        const slug = e.id;     // 移除首尾的连字符
        if (text) {
            headings.push({ depth, slug, text });
        }
    };

    return headings;
}
